{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fTFj8ft5dlbS"
      },
      "source": [
        "##### Copyright 2018 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "lzyBOpYMdp3F"
      },
      "outputs": [],
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "cellView": "form",
        "id": "m_x4KfSJ7Vt7"
      },
      "outputs": [],
      "source": [
        "#@title MIT License\n",
        "#\n",
        "# Copyright (c) 2017 François Chollet\n",
        "#\n",
        "# Permission is hereby granted, free of charge, to any person obtaining a\n",
        "# copy of this software and associated documentation files (the \"Software\"),\n",
        "# to deal in the Software without restriction, including without limitation\n",
        "# the rights to use, copy, modify, merge, publish, distribute, sublicense,\n",
        "# and/or sell copies of the Software, and to permit persons to whom the\n",
        "# Software is furnished to do so, subject to the following conditions:\n",
        "#\n",
        "# The above copyright notice and this permission notice shall be included in\n",
        "# all copies or substantial portions of the Software.\n",
        "#\n",
        "# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n",
        "# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n",
        "# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\n",
        "# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n",
        "# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n",
        "# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER\n",
        "# DEALINGS IN THE SOFTWARE."
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "C9HmC2T4ld5B"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "# الإفراط و التفريط في تعلّم الآلة\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kRTxFhXAlnl1"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"right\" dir=\"rtl\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://www.tensorflow.org/tutorials/keras/overfit_and_underfit?hl=ar\"><img src=\"https://www.tensorflow.org/images/tf_logo_32px.png\" />إفتح المحتوى على موقع TensorFlow.org</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/ar/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />تفاعل مع المحتوى على Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/docs-l10n/blob/master/site/ar/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />إطّلع على المصدر في Github</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a href=\"https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/ar/tutorials/keras/overfit_and_underfit.ipynb\"><img src=\"https://www.tensorflow.org/images/download_logo_32px.png\" />تنزيل الدّفتر</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jQr5vcosbq-d"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "Note: قامت مجموعة المتطوعين في مشروع Tensorflow بترجمة هذا المحتوى. نظرًا لأن هذه الترجمات تعتمد على قاعدة أقصى الجهد (best-effort) ، فلا نضمن أنها انعكاس دقيق وحديث [للمحتوى الرسمي باللغة الإنجليزية](https://www.tensorflow.org/?hl=en). إذا كانت لديك اقتراحات لتحسين هذه الترجمة ، يرجى إرسال \"Pull request\" إلى مشروع [tensorflow/docs-l10n](https://github.com/tensorflow/docs-l10n). للتطوع أو مراجعة ترجمات المجموعة يرجى ارسال ايميل إلى docs@tensorflow.org.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "19rPukKZsPG6"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "كالعادة ، سنستخدم في هذا الدّفتر التّفاعليّ واجهة برمجة التطبيقات `tf.keras` ، والتّي يمكنك معرفة المزيد عنها في [دليل Keras](https://www.tensorflow.org/guide/keras?hl=ar)\n",
        "الموجود على موقع TensorFlow\n",
        ".\n",
        "\n",
        "في المثالين السّابقين - [تصنيف النّصوص](https://www.tensorflow.org/tutorials/keras/text_classification_with_hub?hl=ar) و \n",
        "[التنبؤ بكفاءة الوقود](https://www.tensorflow.org/tutorials/keras/regression?hl=ar) -\n",
        "رأينا أن دقة النّموذج على بيانات التحقق \n",
        "(validation set)\n",
        " ستصل إلى ذروتها بعد عدّة حقبات\n",
        "(epochs)\n",
        "من التّدريب\n",
        "، ومن ثم ستركد أو تبدأ في التناقص.\n",
        "\n",
        "و بعبارة أخرى، فإنّ نموذجنا سوف \n",
        "*يفرط في التعلّم*\n",
        "من بيانات التّدريب\n",
        "، و نقول أيضا يفرط في التخصّص أو يفرط في التّناسب، \n",
        "فتتناسب معلماته (parameters) على هذه البيانات\n",
        "إلى درجة تخلّ بقدرته على العمل بشكل صحيح على بيانات جديدة. \n",
        "تَعَلُّمُ كيفية التعامل مع مشكلة الإفراط في التعلّم أمر في غاية الأهميّة في مجال تعلّم الآلة. \n",
        " على الرغم من أنه غالبًا ما يكون من الممكن تحقيق دقة عالية في *مجموعة التّدريب* ،\n",
        " ما نريده حقًا هو تطوير نماذج قادرة على أن تُعمّم جيدًا ما تعلّمته على بيانات لم تراها أثناء عمليّة التّدريب كتلك الموجودة في\n",
        " *مجموعة الاختبار*.\n",
        "\n",
        "في المقابل، عكس مشكلة الإفراط في التعلّم، هناك مشكلة \n",
        "*التفريط في التعلّم*.\n",
        "تحصُل مشكلة التفريط في التعلّم عندما لا يزال هناك مجال لتحسين أداء النموذج على بيانات الاختبار، إذا تمّ تدريبه لمدّة أطول. \n",
        "يمكن لهذه المشكلة أن تحدث لعدد من الأسباب:\n",
        "إذا كان النموذج بسيطا إلى حدّ أنّه ليس قادرا على تعلّم كُلّ تعقيدات البيانات و الأنماط الموجودة فيها، أو إذا كان مضبوطا بشكل مفرط\n",
        "(over-regularized)،\n",
        "أو ببساطة إذا لم يُدرّب لوقت كافي. \n",
        "وهذا يعني أن نموذج الشبكة العصبيّة المُدرّب لم يتعلم \n",
        "كُلّ الأنماط ذات الصلة \n",
        "(relevant patterns)\n",
        "بالمُهمّة المطلوبة منه\n",
        "رغم أنّها موجودة\n",
        " في بيانات التدريب.\n",
        "\n",
        "Note:\n",
        "يسمّى مفهوم ال\n",
        "overfitting\n",
        "بالعربيّة الإفراط في التعلّم أو الإفراط في التّناسب أو الإفراط في التخصّص. و يسمّى مفهوم ال\n",
        "underfitting\n",
        "التفريط في التعلّم أو التفريط في التناسب أو التفريط في التخصّص. \n",
        "\n",
        "إذا قمت بالتدريب لفترة طويلة جدًا ، فسيبدأ النموذج في ملاءمة وتعلم الأنماط من بيانات التدريب التي لا تُعمّم على بيانات الاختبار أو على بيانات جديدة. نحن بحاجة إلى تحقيق التوازن بين الحاجة إلى تدريب النموذج إلى فترة طويلة بما يكفي لتفادي مشكلة التفريط في التعلّم و لكن ليست طويلة بما يؤدي للوقوع في مشكلة الإفراط في التعلّم. لذا يُعدّ فهم كيفية تحديد العدد المناسب من حقبات التدريب، كما سنستكشف أدناه، مهارة مفيدة.\n",
        "\n",
        "للحيلولة دون الإفراط في التعلّم (أو التخصّص أو التناسب)، فإن أفضل حل هو استخدام بيانات تدريب أكثر اكتمالاً.\n",
        "يجب أن تغطي مجموعة البيانات النطاق الكامل للمُدخلات \n",
        "(inputs)\n",
        "التي من المتوقع أن يتعامل معها النموذج.\n",
        "لذا فإنّ البيانات الإضافية مفيدة فقط إذا كانت تغطي حالات جديدة و مثيرة للاهتمام للمدُخلات. \n",
        "\n",
        "إنّ النّموذج المُدرّب على بيانات أكثر اكتمالاً سيُعمم بشكل طبيعيّ ما تعلّمه بطريقة أفضل. عندما لا يكون ذلك ممكنًا ، فإن أفضل حلٍّ تالي هو استخدام تقنيات مثل تقنية الضبط\n",
        "(regularization).\n",
        "و التّي تضع قيودا على كميّة و نوع المعلومات التّي يمكن للنموذج تخزينها. \n",
        "و تعتمد هذه الطريقة على المبدأ التّالي: \n",
        "إذا كان نموذج الشبكة العصبية لا يستطيع حفظ سوى عدد صغير من الأنماط \n",
        "(patterns)\n",
        "الموجودة في البيانات،\n",
        "بسبب عمليّة الضبط،\n",
        "فإنّ عمليّة التحسين \n",
        "(optimization)\n",
        "ستجبر النموذج على التركير على أبرز الأنماط و أهمّها، و التّي لديها فرصة أفضل للتعميم الجيّد على بيانات جديدة. \n",
        "\n",
        "في هذا الدفتر التفاعليّ، سنستكشف العديد من تقنيات الضبط  الشائعة ، ونستخدمها لتحسين نموذج تصنيف.\n",
        "\n",
        "Note:\n",
        "تسمّى عمليّة ال\n",
        "optimization\n",
        "بالعربيّة التّحسين أو الإستمثال. يُمكنك قراءة المزيد عنها في \n",
        "[هذا المقال](https://ar.wikipedia.org/wiki/استمثال_(رياضيات)).\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WL8UoOTmGGsL"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "## تجهيز بيئة العمل\n",
        "\n",
        "قبل البدأ، قم باستيراد الحزم الضرورية:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "5pZ8A2liqvgk"
      },
      "outputs": [],
      "source": [
        "import tensorflow as tf\n",
        "\n",
        "from tensorflow.keras import layers\n",
        "from tensorflow.keras import regularizers\n",
        "\n",
        "print(tf.__version__)"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QnAtAjqRYVXe"
      },
      "outputs": [],
      "source": [
        "!pip install git+https://github.com/tensorflow/docs\n",
        "\n",
        "import tensorflow_docs as tfdocs\n",
        "import tensorflow_docs.modeling\n",
        "import tensorflow_docs.plots"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-pnOU-ctX27Q"
      },
      "outputs": [],
      "source": [
        "from  IPython import display\n",
        "from matplotlib import pyplot as plt\n",
        "\n",
        "import numpy as np\n",
        "\n",
        "import pathlib\n",
        "import shutil\n",
        "import tempfile\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "jj6I4dvTtbUe"
      },
      "outputs": [],
      "source": [
        "logdir = pathlib.Path(tempfile.mkdtemp())/\"tensorboard_logs\"\n",
        "shutil.rmtree(logdir, ignore_errors=True)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "1cweoTiruj8O"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "## مجموعة بيانات Higgs\n",
        "\n",
        "الهدف من هذا البرنامج التعليمي ليس تعلّم فيزياء الجُسيمات، لذلك لا تركّز كثيرا في تفاصيل مجموعة البيانات. تحتوي مجموعة البيانات هذه على 11000000 مثال، يحتوي كل منها على 28 خاصيّة\n",
        "(feature)\n",
        " ، و على تسمية فئة ثنائية\n",
        " (binary class label).\n",
        "\n",
        "Note: نستعمل في العربيّة كلمة خاصيّة أو ميزة للإشارة إلى مفهوم Feature المستعمل في تعلّم الآلة.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "YPjAvwb-6dFd"
      },
      "outputs": [],
      "source": [
        "gz = tf.keras.utils.get_file('HIGGS.csv.gz', 'http://mlphysics.ics.uci.edu/data/higgs/HIGGS.csv.gz')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "AkiyUdaWIrww"
      },
      "outputs": [],
      "source": [
        "FEATURES = 28"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SFggl9gYKKRJ"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "يمكن استخدام فئة\n",
        "`tf.data.experimental.CsvDataset`\n",
        "لقراءة سجلات\n",
        "csv \n",
        "مباشرة من ملفّ مضغوط بتقنية\n",
        "gzip\n",
        "دون القيام بخطوة فكّ الضغط\n",
        "(decompression)\n",
        "بالطريقة التّالية.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QHz4sLVQEVIU"
      },
      "outputs": [],
      "source": [
        "ds = tf.data.experimental.CsvDataset(gz,[float(),]*(FEATURES+1), compression_type=\"GZIP\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HzahEELTKlSV"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تقوم فئة قراءة سجلّات \n",
        "csv\n",
        "السابقة بإرجاع قائمة أعداد لكُلّ سِجلّ. \n",
        "و تعيد الوظيفة التّالية إدارج قائمة الأعداد في كُلّ سجلّ \n",
        "إلى زوجٍ مكوَّن من\n",
        "(feature_vector ، label).\n",
        "حيث أنّ\n",
        "feature_vector\n",
        "تحتوى على خصيّات المثال الموجود في السجلّ و يحتوى \n",
        "label\n",
        "على تسميته الحقيقية. \n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "zPD6ICDlF6Wf"
      },
      "outputs": [],
      "source": [
        "def pack_row(*row):\n",
        "  label = row[0]\n",
        "  features = tf.stack(row[1:],1)\n",
        "  return features, label"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4oa8tLuwLsbO"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "صُمِّمَ\n",
        "TensorFlow\n",
        "ليعمل بشكل أكثر فعاليّة على \n",
        "دفعات كبيرة من البيانات. \n",
        "\n",
        " لذا بدلاً من إستخراج أزواج البيانات باستعمال الوظيفة السابقة على كُلّ سجلّ على حدة،\n",
        "قم بتجهيز وظيفة\n",
        "`Dataset`\n",
        "أي وظيفة\n",
        "`مجموعة بيانات`\n",
        "جديدة تأخذ دفعات من البيانات متكوّنة من\n",
        "10000 مثال،\n",
        "ثمّ تطبّق الوظيفة \n",
        "`pack_row`\n",
        "على كُلّ هذه الأمثلة في آن واحد، \n",
        "ثمّ تقسّم الدفعات إلى سجلاّت فردية مرّة أخرى. يمكنك القيام بذلك هكذا:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "-w-VHTwwGVoZ"
      },
      "outputs": [],
      "source": [
        "packed_ds = ds.batch(10000).map(pack_row).unbatch()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lUbxc5bxNSXV"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "ألق نظرة على بعض الأمثلة الموجودة في المتغيّر الجديد\n",
        "`packed_ds`.\n",
        "\n",
        "كما هو ظاهر، فإن قيم الميزات \n",
        "ليست معيّرة \n",
        "(not normalized)\n",
        "بشكل تامّ،\n",
        "و لكنّ حالتها هذه كافية لما نريد أن نتعلّمه في هذا الدرس.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "TfcXuv33Fvka"
      },
      "outputs": [],
      "source": [
        "for features,label in packed_ds.batch(1000).take(1):\n",
        "  print(features[0])\n",
        "  plt.hist(features.numpy().flatten(), bins = 101)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ICKZRY7gN-QM"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "ليكون وقت تدريب النماذج قصيرا نسبيّا حتّى تتمكّن من اتمام البرنامج التعليمي، استخدم أوّل 1000 عيّنة كمجموعة تحقّق،\n",
        "و ال10000 التّالية للتدريب:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "hmk49OqZIFZP"
      },
      "outputs": [],
      "source": [
        "N_VALIDATION = int(1e3)\n",
        "N_TRAIN = int(1e4)\n",
        "BUFFER_SIZE = int(1e4)\n",
        "BATCH_SIZE = 500\n",
        "STEPS_PER_EPOCH = N_TRAIN//BATCH_SIZE"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "FP3M9DmvON32"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تسهّل طريقتا `Dataset.skip` و` Dataset.take` ذلك.\n",
        "\n",
        "في الوقت نفسه ، استخدم طريقة `Dataset.cache` للتأكد من أن قارئ البيانات لا يحتاج إلى إعادة قراءتها من الملف في كل حقبة من حقبات عمليّة التّدريب:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "H8H_ZzpBOOk-"
      },
      "outputs": [],
      "source": [
        "validate_ds = packed_ds.take(N_VALIDATION).cache()\n",
        "train_ds = packed_ds.skip(N_VALIDATION).take(N_TRAIN).cache()"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "9zAOqk2_Px7K"
      },
      "outputs": [],
      "source": [
        "train_ds"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "6PMliHoVO3OL"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تُرجع الطرق السابقة مجموعة بيانات متكوّنة من أمثلة فرديّة.\n",
        "استخدم طريقة\n",
        "`batch`\n",
        "لتحويل مجموعة البيانات إلى دفعات ذات حجم مناسب للتدريب.\n",
        "قبل إنشاء الدفعات، تذكّر بأن \n",
        "تخلط البيانات باستعمال \n",
        "`shuffle`\n",
        "و أن تسمح بتكرار السجلات لاتمام الدفعات باستعمال\n",
        "`repeat`. \n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Y7I4J355O223"
      },
      "outputs": [],
      "source": [
        "validate_ds = validate_ds.batch(BATCH_SIZE)\n",
        "train_ds = train_ds.shuffle(BUFFER_SIZE).repeat().batch(BATCH_SIZE)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "lglk41MwvU5o"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "## برهنة الإفراط في التعلّم\n",
        "\n",
        "إن أبسط طريقة لمنع الإفراط في التعلّم هي البدء بنموذج صغير: أي نموذج به عدد صغير من \n",
        "المعلمات \n",
        "(parameters)\n",
        "التي يجب تعلّمها (و عددها الجمليّ يحدده عدد الطبقات و عدد الوحدات في كل طبقة). في التعلّم العميق، غالبًا ما يُشار إلى عدد المعلمات القابلة للتعلّم في النموذج باسم \"سَعَةِ\" \n",
        "النموذج\n",
        "(model's capacity).\n",
        "\n",
        "بديهيّا ، النموذج الذي يحتوي على المزيد من المعلمات سيكون له \"سعة حفظ\" أكبر ، وبالتالي سيكون قادرًا على استنتاج و حفظ ما يشبه قاموسا يَقرِنُ فيه بين عيّنات التدريب و أهدافها (تسمياتها).\n",
        "و لكن هذا القاموس لن تكون له أيّ \n",
        "قدرة على التعميم\n",
        "(generalization power).\n",
        "و هذا لن يكون مفيدا عند القيام بتنبؤات على بيانات لم يراها النموذج من قبل. \n",
        "\n",
        "ضع التّالي دائمًا في الاعتبار: تميل نماذج التعلّم العميق إلى ملاءمة بيانات التدريب بشكل جيّد ، ولكن التحدي الحقيقي هو قدرة النموذج على التعميم ، وليس قدرته على ملاءمة بيانات التدريب.\n",
        "\n",
        "من ناحية أخرى ، إذا كانت قدرة الشبكة على الحفظ محدودة، فلن تتمكن من تعلّم أو استنتاج  قاموس الإقتران بين بيانات التدريب و تسميتها بسهولة.\n",
        "لذا، لتقليل خسارتها، سيتعين عليها تعلُّمُ تمثيلات مضغوطة \n",
        "(compressed representations)\n",
        " لها قوة تنبؤية أكبر.\n",
        " ولكن، في الوقت نفسه، إذا جعلت النموذج صغيرًا جدًا، فسيجد صعوبة في ملاءمة بيانات التدريب و التعلّم منها. لذا يجب إيجاد التوازن بين \"السعة الزائدة\" و \"السعة غير الكافية\" للنموذج.\n",
        "\n",
        "لسوء الحظ، لا توجد صيغة سحرية لتحديد الحجم أو البنية الصحيحة لنموذجك (من حيث عدد الطبقات ، أو الحجم المناسب لكل طبقة). سيكون \n",
        "عليك تجربة عددٍ من بِنَى الشبكات العصبيّةالمختلفة.\n",
        "\n",
        "للعثور على حجم نموذج مناسب، من الأفضل أن تبدأ بطبقات ومعلمات قليلة نسبيًا، ثم تبدأ في زيادة حجم الطبقات أو إضافة طبقات جديدة حتى ترى تناقصًا في عائدات هذه الزيادات على أداء النموذج في بيانات التحقّق. و يكون ذلك عن طريق مراقبة تطوّر قيمة دالّة الخسارة على بيانات التحقّق.\n",
        "\n",
        "ابدأ بنموذج بسيط باستخدام طبقات\n",
        "`layers.Dense`\n",
        "فقط كنموذجٍ مبدئي\n",
        "(baseline)،\n",
        "ثمّ أنشئ إصدارات جديدة من النموذج بزيادة عدد الطبقات أو عدد المعلمات فيها و قارن أداء كُلّ إصدار للنموذج مع أداء الإصدار السّابق.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "_ReKHdC2EgVu"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### طريقة التدريب\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "pNzkSkkXSP5l"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تتدرّب العديد من النماذج بشكل أفضل إذا قمت بتقليل معدّل التعلّم\n",
        "(learning rate)\n",
        "بشكل تدريجي أثناء التدريب. استخدم\n",
        "`optimizers.schedules`\n",
        "لتقليل معدّل التعلّم\n",
        "بمرور الوقت:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LwQp-ERhAD6F"
      },
      "outputs": [],
      "source": [
        "lr_schedule = tf.keras.optimizers.schedules.InverseTimeDecay(\n",
        "  0.001,\n",
        "  decay_steps=STEPS_PER_EPOCH*1000,\n",
        "  decay_rate=1,\n",
        "  staircase=False)\n",
        "\n",
        "def get_optimizer():\n",
        "  return tf.keras.optimizers.Adam(lr_schedule)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kANLx6OYTQ8B"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "يحدد الكود أعلاه \"جدولا زمنيا\" باستعمال الوظيفة \n",
        "`schedules.InverseTimeDecay`\n",
        "لخفض معدل التعلّم بشكل زائدي\n",
        "(hyperbolically)\n",
        "إلى 1/2 (نصف) القيمة الأولى لمعدّل التعلّم عند بلوغ 1000 حقبة،\n",
        "و إلى 1/3 (ثلث) القيمة الأولى عند بلوغ 2000 حقبة و هكذا دواليك.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "HIo_yPjEAFgn"
      },
      "outputs": [],
      "source": [
        "step = np.linspace(0,100000)\n",
        "lr = lr_schedule(step)\n",
        "plt.figure(figsize = (8,6))\n",
        "plt.plot(step/STEPS_PER_EPOCH, lr)\n",
        "plt.ylim([0,max(plt.ylim())])\n",
        "plt.xlabel('Epoch')\n",
        "_ = plt.ylabel('Learning Rate')\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ya7x7gr9UjU0"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "سيستخدم كل نموذج في هذا الدرس نفس إعدادات التدريب. لذا قم بإعدادها بطريقة قابلة لإعادة الاستخدام ، بدءًا من قائمة الوظائف القابلة للإستدعاء أتوماتكيّا\n",
        "(callbacks).\n",
        "\n",
        "تمتدّ عمليّة التدريب في هذا الدّرس لعدّة حِقَبٍ قصيرة (epochs).\n",
        "لتقليل الضوضاء الناتجة عن تسجيل (logging) معلومات الإشراف على التدريب،\n",
        "استخدم `tfdocs.EpochDots`\n",
        "و التّي، ببساطة، ستضع نقطة \".\" لتمثّل كُلّ حقبة، و مجموعة من المقاييس كل 100 حقبة من التّدريب.\n",
        "\n",
        "بعد ذلك، قم بتضمين الوظيفة\n",
        "`callbacks.EarlyStopping`\n",
        "في مجموعة الوظائف القابلة للإستدعاء\n",
        "(callbacks)\n",
        "و التّى ستقوم بإيقاف التّدريب مبكّرا، عند تحقق بعض الشروط، لتجنّب أوقات التّدريب الطويلة و غير الضروريّة. \n",
        "لا حظ أنّ هذه الوظيفة سوف تُراقب قيمة \n",
        "المتغيّر `val_binary_crossentropy`،\n",
        "و ليس المتغيّر\n",
        "`val_loss`.\n",
        "سنرى لاحقّا أنّ هذا الاختلاف مهم.\n",
        "\n",
        "استخدم\n",
        "`callbacks.TensorBoard`\n",
        " لإنشاء سجلاّت تمكّنك من الإشراف على عمليّة التّدريب و مراقبة تقدّمها باستعمال\n",
        "TensorBoard.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "vSv8rfw_T85n"
      },
      "outputs": [],
      "source": [
        "def get_callbacks(name):\n",
        "  return [\n",
        "    tfdocs.modeling.EpochDots(),\n",
        "    tf.keras.callbacks.EarlyStopping(monitor='val_binary_crossentropy', patience=200),\n",
        "    tf.keras.callbacks.TensorBoard(logdir/name),\n",
        "  ]"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "VhctzKhBWVDD"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "وبالمثل ، سيستخدم كل نموذج نفس الإعدادات \n",
        "في الوظيفتان\n",
        "`Model.compile` و` Model.fit`:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "xRCGwU3YH5sT"
      },
      "outputs": [],
      "source": [
        "def compile_and_fit(model, name, optimizer=None, max_epochs=10000):\n",
        "  if optimizer is None:\n",
        "    optimizer = get_optimizer()\n",
        "  model.compile(optimizer=optimizer,\n",
        "                loss=tf.keras.losses.BinaryCrossentropy(from_logits=True),\n",
        "                metrics=[\n",
        "                  tf.keras.losses.BinaryCrossentropy(\n",
        "                      from_logits=True, name='binary_crossentropy'),\n",
        "                  'accuracy'])\n",
        "\n",
        "  model.summary()\n",
        "\n",
        "  history = model.fit(\n",
        "    train_ds,\n",
        "    steps_per_epoch = STEPS_PER_EPOCH,\n",
        "    epochs=max_epochs,\n",
        "    validation_data=validate_ds,\n",
        "    callbacks=get_callbacks(name),\n",
        "    verbose=0)\n",
        "  return history"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mxBeiLUiWHJV"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### نموذج بالغ الصّغر\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "a6JDv12scLTI"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "ابدأ بتدريب النموذج التّالي:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "EZh-QFjKHb70"
      },
      "outputs": [],
      "source": [
        "tiny_model = tf.keras.Sequential([\n",
        "    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(1)\n",
        "])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "X72IUdWYipIS"
      },
      "outputs": [],
      "source": [
        "size_histories = {}"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "bdOcJtPGHhJ5"
      },
      "outputs": [],
      "source": [
        "size_histories['Tiny'] = compile_and_fit(tiny_model, 'sizes/Tiny')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "rS_QGT6icwdI"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تحقق الآن من أداء النموذج:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dkEvb2x5XsjE"
      },
      "outputs": [],
      "source": [
        "plotter = tfdocs.plots.HistoryPlotter(metric = 'binary_crossentropy', smoothing_std=10)\n",
        "plotter.plot(size_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "LGxGzh_FWOJ8"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### نموذج صغير\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YjMb6E72f2pN"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "لمعرفة ما إذا كان بإمكانك التغلّب على أداء النّموذج بالغ الصّغر السّابق، قم بتدريب بعض النماذج الأكبر تدريجيًا.\n",
        "\n",
        "جرّب إضافة طبقتين مخفيّتين \n",
        "(hidden layers)\n",
        "تحتوى كُلٌّ منهما على 16 وحدة:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "QKgdXPx9usBa"
      },
      "outputs": [],
      "source": [
        "small_model = tf.keras.Sequential([\n",
        "    # `input_shape` is only required here so that `.summary` works.\n",
        "    layers.Dense(16, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(16, activation='elu'),\n",
        "    layers.Dense(1)\n",
        "])"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "LqG3MXF5xSjR"
      },
      "outputs": [],
      "source": [
        "size_histories['Small'] = compile_and_fit(small_model, 'sizes/Small')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "L-DGRBbGxI6G"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### نموذج متوسط\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "SrfoVQheYSO5"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "جرب الآن إضافة 3 طبقات مخفية مع 64 وحدة لكل منها:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "jksi-XtaxDAh"
      },
      "outputs": [],
      "source": [
        "medium_model = tf.keras.Sequential([\n",
        "    layers.Dense(64, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(64, activation='elu'),\n",
        "    layers.Dense(64, activation='elu'),\n",
        "    layers.Dense(1)\n",
        "])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "jbngCZliYdma"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "وقم بتدريب النموذج باستخدام نفس البيانات:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "Ofn1AwDhx-Fe"
      },
      "outputs": [],
      "source": [
        "size_histories['Medium']  = compile_and_fit(medium_model, \"sizes/Medium\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vIPuf23FFaVn"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "###نموذج كبير\n",
        "\n",
        "كتمرين ، يمكنك إنشاء نموذج أكبر ، و مراقبته للنظر في سرعة بدءه في الإفراط في التناسب\n",
        "(أي الإفراط في التعلّم أو التخصصّ).\n",
        "بعد ذلك ، دعنا نضيف إلى مقارنة النماذج هذه شبكة ذات سعة أكبر بكثير ، أكثر مما تتطلبه المشكلة:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "ghQwwqwqvQM9"
      },
      "outputs": [],
      "source": [
        "large_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dense(1)\n",
        "])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "D-d-i5DaYmr7"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "ومرة أخرى ، قم بتدريب النموذج باستخدام نفس البيانات:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "U1A99dhqvepf"
      },
      "outputs": [],
      "source": [
        "size_histories['large'] = compile_and_fit(large_model, \"sizes/large\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Fy3CMUZpzH3d"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### رسم تطوّر قيمة دالّة الخسارة على بيانات التدريب و بيانات التحقّق\n",
        "\n",
        "</div>\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HSlo1F4xHuuM"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تُظهر الخطوط المتواصلة  تطوّر الخسارة على بيانات التدريب، وتظهر الخطوط المتقطعة  تطوّر الخسارة على بيانات التحقق (تذكير: كُلّما كانت الخسارة أقّل على بيانات التحقّق كُلّما كان النموذج أفضل).\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "OLhL1AszdLfM"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "في حين أن بناء نموذج أكبر يعني أنّ هذا النموذج سيكون لديه المزيد من القوة و سعة الإستعاب للتعلّم ، و لكن إذا لم تكن هذه القوة مقيّدة بطريقة ما، فيمكن بسهولة لهذا النموذج أن يُفرط في التعلّم من مجموعة التدريب و تتناسب معلماته \n",
        "(parameters)\n",
        "معها.\n",
        "\n",
        "في هذا المثال، عادةً، ما يتمكن النموذج\n",
        "`\"بالغ الصّغر\"`\n",
        "فقط من تجنب الوقوع في مشكلة الإفراط في التخصّص، وكل نموذج من النماذج الأكبر يقع في هذه المشكلة بسرعة أكبر كُلّما كان النموذج أكبر.\n",
        "تصبح هذه الظّاهرة شديدة التأثير على النموذج الكبير إلى حدّ أنّنا نحتاج إلى استعمال مقياس لوغاريتمي \n",
        "(log-scale)\n",
        "في أيّ رسم بياني حتّى نتمكّن من رؤية و مقارنة تطوّر الخسارة على بيانات التدريب و بيانات التحقّق.\n",
        "\n",
        "هذا واضح إذا قمت برسم ومقارنة مقاييس التحقق بمقاييس التدريب.\n",
        "و عند المقارنة يجب أخذ النقاط التّالية في عين الإعتبار:\n",
        "\n",
        "* من الطبيعي أن يكون هناك اختلاف بسيط في قيم مقياس ما بين مجموعتَي البيانات (التدريب و التحقّق).\n",
        "* إذا كان كلا المقياسين يتحركان في نفس الاتجاه ، فكل شيء على ما يرام.\n",
        "* إذا بدأ مقياس التحقق في الركود بينما يستمر مقياس التدريب في التحسن ، فربما تكون على وشك الإفراط في التعلّم.\n",
        "* إذا كان مقياس التحقق يسير في الاتجاه الخاطئ، فمن الواضح أن النموذج مفرط في التخصّص.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "0XmKDtOWzOpk"
      },
      "outputs": [],
      "source": [
        "plotter.plot(size_histories)\n",
        "a = plt.xscale('log')\n",
        "plt.xlim([5, max(plt.xlim())])\n",
        "plt.ylim([0.5, 0.7])\n",
        "plt.xlabel(\"Epochs [Log Scale]\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "UekcaQdmZxnW"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "Note: اِستخدمت جميع دورات التدريب المذكورة أعلاه \n",
        "الوظيفة القابلة للاستدعاء\n",
        "`callbacks.EarlyStopping`\n",
        "و التّي تمكّن من الإيقاف المبكّر للتدريب. و هي تقوم بإنهاء عمليّة التدريب بمجرّد أن يتضّح أنّ النّموذج لم يعد يحرز أي تقّدم بمواصلة عمليّة التدريب. \n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "DEQNKadHA0M3"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### عرض سجلاّت الإشراف على التدريب في TensorBoard\n",
        "\n",
        "جميع هذه النماذج كتبت سجلات TensorBoard أثناء التدريب.\n",
        "\n",
        "يمكنك أن تفتح عارض\n",
        "TensorBoard\n",
        "مضمّن داخل هذا الدّفتر التفاعلي هكذا:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "6oa1lkJddZ-m"
      },
      "outputs": [],
      "source": [
        "#docs_infra: no_execute\n",
        "%tensorboard --logdir {logdir}/sizes"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "fjqx3bywDPjf"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "يمكنك عرض [نتائج إحدى دورات التدريب السابقة](https://tensorboard.dev/experiment/vW7jmmF9TmKmy3rbheMQpw/#scalars&_smoothingWeight=0.97) لهذا الدفتر التّفاعلي على موقع [TensorBoard.dev](https://tensorboard.dev/).\n",
        "\n",
        "يُمكّن موقع\n",
        "TensorBoard.dev\n",
        "من استضافة وتتبع ومشاركة تجارب\n",
        "تعلّم الآلة\n",
        "(ML)\n",
        "مع الجميع.\n",
        "\n",
        "يتم تضمينه أيضًا في \n",
        "`<iframe>`\n",
        "لتيسير التّعامل مع \n",
        "TensorBoard\n",
        "في هذا الدّفتر التفاعليّ:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "dX5fcgrADwym"
      },
      "outputs": [],
      "source": [
        "display.IFrame(\n",
        "    src=\"https://tensorboard.dev/experiment/vW7jmmF9TmKmy3rbheMQpw/#scalars&_smoothingWeight=0.97\",\n",
        "    width=\"100%\", height=\"800px\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "RDQDBKYZBXF_"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "إذا كنت ترغب في مشاركة نتائج\n",
        "TensorBoard\n",
        "لتجربتك، فيمكنك تحميل السجلات إلى\n",
        "[TensorBoard.dev](https://tensorboard.dev/)\n",
        "عن طريق نسخ ما يلي في خلية تعليمات برمجية في هذا الدفتر.\n",
        "\n",
        "Note: تتطلب هذه الخطوة حسابًا على Google.\n",
        "\n",
        "</div>\n",
        "\n",
        "```\n",
        "!tensorboard dev upload --logdir  {logdir}/sizes\n",
        "```\n",
        "\n",
        "<div dir=\"rtl\">\n",
        "\n",
        "Caution: تنفيذ الأمر البرمجي السّابق لن ينتهي من تلقاء نفسه. فقد تم تصميمه لتحميل نتائج التجارب التّي يمكن أن تستمرّ لوقت طويل.\n",
        "لذا، و بمجرد تحميل بياناتك، تحتاج إلى إيقافه باستخدام خيار\n",
        "\"interrupt execution\"\n",
        "(إيقاف التنفيذ)\n",
        "الموجود في الدّفتر التفاعليّ.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "ASdv7nsgEFhx"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "## استراتيجيات منع الإفراط في التعلّم\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "YN512ksslaxJ"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "قبل الدخول في محتوى هذا القسم، انسخ سجلات التدريب من النموذج\n",
        "`\"الصغير جدّا\"`\n",
        "أعلاه، لاستخدامه كخط مرجعي للمقارنة.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "40k1eBtnQzNo"
      },
      "outputs": [],
      "source": [
        "shutil.rmtree(logdir/'regularizers/Tiny', ignore_errors=True)\n",
        "shutil.copytree(logdir/'sizes/Tiny', logdir/'regularizers/Tiny')"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "vFWMeFo7jLpN"
      },
      "outputs": [],
      "source": [
        "regularizer_histories = {}\n",
        "regularizer_histories['Tiny'] = size_histories['Tiny']"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4rHoVWcswFLa"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### إضافة ضبط الأوزان (weight regularization)\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "kRxWepNawbBK"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "قد تكون على دراية بمبدأ Occam's Razor \n",
        "و الذّي يقول: باعتبار شرحين لشيء ما، من المرجّح أن يكون التفسير \"الأبسط\" هو الأصحّ، أي التفسير الذي يَستعمل أقلّ قدر من الافتراضات المسبقة\n",
        "(assumptions).\n",
        "ينطبق هذا أيضًا على النماذج التي تتعلمها الشبكات العصبية و يكمُن وجه المقارنة في التّالي: إذا أخذنا بعض بيانات التدريب و تصميم شبكة عصبيّة ما، فهناك مجموعات متعددة من قيم الأوزان (أي نماذج متعددة) التّي يُمكنها أن تفسّر البيانات، والنماذج الأبسط أقل عرضة لمشكلة الإفراط في التناسب من النماذج المعقدة.\n",
        "\n",
        "في هذا السياق، \"النموذج البسيط\" هو نموذج يكون توزيع \n",
        "قيم المعلمات\n",
        "(parameters)\n",
        " فيه إنتروبيا أقل - has less entropy - \n",
        "(أو إذا احتوى النموذج بأسره على معلمات أقلّ ، كما رأينا في القسم السّابق من هذا الدّرس). وبالتالي فإن الطريقة الشائعة لتخفيف الإفراط في التعلّم هي وضع قيود على تعقيد نموذج الشبكة العصبيّة عن طريق إجبار أوزانها على أخذ قيم صغيرة فقط، مما يجعل توزيع قيم الأوزان \"أكثر انتظامًا\". وهذا ما يسمى \"ضبط الوزن\"\n",
        "(weight regularization)،\n",
        " ويتم ذلك عن طريق إضافة تكلفة مرتبطة بالأوزان الكبيرة إلى دالّة الخسارة في نموذج الشبكة. تأتي هذه التكلفة في صيغتين:\n",
        "\n",
        "* [الضبط بطريقة L1](https://developers.google.com/machine-learning/glossary/#L1_regularization)، حيث تتناسب التكلفة المضافة مع القيمة المطلقة للأوزان (\n",
        "ولذلك تسمّى أيضا\n",
        "\"معيار L1\"\n",
        "للأوزان).\n",
        "\n",
        "* [الضبط بطريقة L2](https://developers.google.com/machine-learning/glossary/#L2_regularization)، حيث تتناسب التكلفة المضافة مع مربع قيمة الأوزان (أي ما يسمى\n",
        "\"معيار L2\"\n",
        "التربيعي\n",
        "للأوزان).\n",
        "و تسمّى هذه الطريقة أيضا\n",
        "\"اضمحلال الوزن\"\n",
        "(weight decay)\n",
        "في سياق مجال الشبكات العصبيّة.\n",
        "لا تدع إختلاف الأسماء يربكك: فمن منطلق رياضيّ اضمحلال الوزن يساوي تماما طريقة الضبط باستعمال معيار \n",
        "L2.\n",
        "\n",
        "يؤدي الضبط بطريقة \n",
        "L1\n",
        "إلى دفع الأوزان إلى الصفر حرفيّا و هو ما يُنتج نموذجًا قليل الكثافة - و يسمّى أيضا نموذجا متناثرًا\n",
        "(sparse model).\n",
        "وأمّا طريقة الضبط باستعمال\n",
        "L2\n",
        "ستُعاقب \n",
        "  الأوزان دون جعلها متناثرة أو قليلة الكثافة و ذلك لأنّ قيمة هذه \"التكلفة الزائدة\" أو العقوبة ستكون قريبة إلى الصفر للأوزان الصغيرة.\n",
        "و هذا أحد الأسباب التّي تجعل طريقة\n",
        "L2\n",
        "أكثر شيوعا.\n",
        "\n",
        "في\n",
        "`tf.keras`،\n",
        "ضبط الأوزان يتمّ عن طريق تمرير وظائف الضبط إلى طبقات شبكة عصبيّة ما كإعداد من إعداداتها.\n",
        "فلنضف ضبط الأوزان بطريقة\n",
        "L2\n",
        "لنموذجنا ليصير كالتّالي:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "HFGmcwduwVyQ"
      },
      "outputs": [],
      "source": [
        "l2_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001),\n",
        "                 input_shape=(FEATURES,)),\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001)),\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001)),\n",
        "    layers.Dense(512, activation='elu',\n",
        "                 kernel_regularizer=regularizers.l2(0.001)),\n",
        "    layers.Dense(1)\n",
        "])\n",
        "\n",
        "regularizer_histories['l2'] = compile_and_fit(l2_model, \"regularizers/l2\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bUUHoXb7w-_C"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "استعمال الدّالة\n",
        "`l2`\n",
        "بهذا الشكل\n",
        "`l2(0.001)`\n",
        "يعني أن كل معامل\n",
        "(coefficient) \n",
        "في مصفوفة أوزان طبقة ما، سيضيف قيمة خسارة إضافيّة إلي إجماليّ خسارة الشبكة باستعمال المعادلة التّالية:\n",
        "`0.001 * weight_coefficient_value**2`.\n",
        "\n",
        "هذا هو السبب في أننا نراقب \n",
        "`binary_crossentropy`\n",
        "مباشرة، لأنه لا يحتوي على مكون الضبط \n",
        "(regularization component).\n",
        "\n",
        "لذا ، فإن النموذج `\"الكبير\"` سيكون أداءه أفضل\n",
        "باستعمال الضبط بمعيار\n",
        "L2\n",
        "كعقوبة إضافيّة مع إجماليّ قيمة دالّة الخسارة:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7wkfLyxBZdh_"
      },
      "outputs": [],
      "source": [
        "plotter.plot(regularizer_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "Kx1YHMsVxWjP"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "كما ترى ، فإن النموذج المضبوط\n",
        "(regularized model)\n",
        "باستعمال معيار \n",
        "\"L2\"\n",
        "أصبح الآن أكثر قدرة على المنافسة مع النموذج الأوّل\n",
        "`\"بالغ الصّغر\"`.\n",
        "هذا النموذج \n",
        "`\"الكبير\"`\n",
        "المضبوط ب\n",
        "\"L2\"\n",
        "هو أيضا أكثر مقاومة و صمودا أمام مشلكة الإفراط في التعلّم مقارنة بالنموذج\n",
        "`\"الكبير\"`\n",
        "السّابق الذّي لم يحتوي على ضبط\n",
        "\"L2\"\n",
        "و ذلك على الرغم من احتواء كلا النموذجان على نفس عدد .المعلمات\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "JheBk6f8jMQ7"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "#### معلومات إضافية \n",
        "\n",
        "هناك شيئان مهمان يجب ملاحظتهما حول هذا النوع من الضبط\n",
        "(regularization).\n",
        "\n",
        "**أولاً:** إذا كنت بصدد كتابة حلقة التدريب\n",
        "(training loop)\n",
        " الخاصة بك ، فأنت بحاجة إلى أن تستخرج من النموذج خسائره المتعلّقة بالضبط\n",
        "(regularization losses).\n",
        "و يمكن القيام بذلك هكذا:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "apDHQNybjaML"
      },
      "outputs": [],
      "source": [
        "result = l2_model(features)\n",
        "regularization_loss=tf.add_n(l2_model.losses)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "MLhG6fMSjE-J"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "**ثانيًا:** طريقة استعمال الضبط السابقة تعتمد على إضافة عقوبات للأوزان\n",
        "(weight penalties)\n",
        "إلى القيمة الجمليّة للخسارة،\n",
        "ثمّ استعمال أي إجراء من إجراءات التحسين المعهودة\n",
        "(مثل gradient descent)\n",
        "بعد ذلك.\n",
        "\n",
        "هناك نهجٌ ثانٍ لاستعمال الضبط يقوم على تشغيل المحسّن فقط على الخسارة الأولية (من دون القيمة المضافة من عمليّة الضبط)، وبعد ذلك أثناء تطبيق خطوة إعادة حساب قيم الأوزان، يقوم المحسّن بحسابات إضافية تؤدّي إلى اضمحلال الأوزان إلى درجة ما.\n",
        "هذه الطريقة التّي تؤدّي إلى \"إضمحلال الأوزان بشكل منفصل\"\n",
        "(\"Decoupled Weight Decay\")\n",
        " يمكن إيجادُها في بعض المحسّنات\n",
        "(optimizers)\n",
        "مثل\n",
        "`optimizers.FTRL` و` Optizers.AdamW`.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "HmnBNOOVxiG8"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### الإسقاط العشوائي (Dropout)\n",
        "\n",
        "تقنية الإسقاط العشوائي أو \n",
        "Dropout\n",
        "هي واحدة من أكثر تقنيات الضبط فاعليّة و هي شائعة الاستعمال خاصّة لضبط نماذج الشبكات العصبيّة.\n",
        "وقع تطويرها من قبل \n",
        "Geoffrey Hinton\n",
        "و طلبته في جامعة تُورنتو الكنديّة.\n",
        "\n",
        "التفسير البديهي لطريقة عمل تقنيّة الإسقاط العشوائي\n",
        "(dropout)\n",
        "هي أنّه باستعمال هذه التقنيّة فإنّ كُلّ خليّة عصبيّة ، أو عقدة، من الشبكة العصبيّة ستستنتج بأنّها لا تستطيع أن تعتمد على مُخرجات\n",
        "(outputs)\n",
        "الخلايا الأخرى، فتضطرّ إلى أن تستخرج بنفسها أهمّ الميزات و الخصائص الموجودة في البيانات التّى تصل إليها و التّى تمكّنها من العمل بشكل أصحّ دون الإعتماد على غيرها.\n",
        "\n",
        "يتمثّل الإسقاط العشوائي، المطبّق على طبقة شبكة عصبيّة ما، في تجاهل بعض الخاصّيات المُخرجة\n",
        "(output features)\n",
        " من طبقة ما بطريقة عشوائية، و نعنى بتجاهلها أو إسقاطها  تحويل قيمتها إلى صفر. لنفترض كمثال أنّ لدينا طبقة تخرج عادة متوجّهًا\n",
        "(vector)\n",
        "كالتّالي\n",
        "`[0.2, 0.5, 1.3, 0.8, 1.1]`\n",
        "بعد إدخال مثال من البيانات أثناء عمليّة التدريب؛\n",
        "بعض تطبيق تقنية الإسقاط العشوائي،\n",
        "سيحتوى المتوجّه السابق على عدّة أصفار موزعة بشكل عشوائي، مثال:\n",
        "`[0, 0.5, 1.3, 0, 1.1]`.\n",
        "\n",
        "نسمّي \"معدّل الإسقاط\" الجزء من الميزات، في طبقة ما، الذّي يتمّ تجاهله أو استبعاده (بتحويله إلى أصفار)؛\n",
        "و تكون قيمة هذا المعدّل عادة بين 0.2 و 0.5. \n",
        "لا يتمّ استخدام تقنية الإسقاط العشوائي عند اختبار النموذج، أي لا يتمّ استبعاد أيٍّ من مُخرجات خلايا أي طبقة من الشبكة، بدلاً من ذلك يتمّ تصغير قيم المُخرجات بعامل يساوي قيمة \"معدّل الإسقاط\" السّابق حتّى نأخذ في عين الإعتبار أنّ عدد خلايا الشبكة النشطة عند الاختبار أكبر من عددها عند التدريب.\n",
        "\n",
        "في\n",
        "`tf.keras`\n",
        "يمكنك استعمال تقنية الإسقاط العشوائي \n",
        "(dropout)\n",
        "عبر إضافة طبقة\n",
        "Dropout\n",
        "و التّى يتمّ تطبيقها على إخراج الطبقة السّابقة لها مباشرة. \n",
        "\n",
        "لنضف طبقتي \n",
        "Dropout\n",
        "لشبكتنا لنرى مدى نجاحهما في الحدّ من مشكلة الإفراط في التعلّم:\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "OFEYvtrHxSWS"
      },
      "outputs": [],
      "source": [
        "dropout_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(1)\n",
        "])\n",
        "\n",
        "regularizer_histories['dropout'] = compile_and_fit(dropout_model, \"regularizers/dropout\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "SPZqwVchx5xp"
      },
      "outputs": [],
      "source": [
        "plotter.plot(regularizer_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "4zlHr4iaI1U6"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "من الواضح من الرسم البياني أنّ تقنيتي الضبط المدروستان سابقا يحسّنان أداء النموذج\n",
        "`\"الكبير\"`.\n",
        "و لكن، رغم ذلك، لا يتخطّى أداء النموذج الكبير أداء  النموذج بالغ الصّغر الذّي نستعمله كخطّ مرجعي.\n",
        "\n",
        "في التّالي، سنجرّب تقنيتي الضبط معًا لنرى إن كان ذلك سيؤدّي إلي تحسين أداء النموذج.\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "u7qMg_7Nwy5t"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### تجربة تقنتي الضبط L2 و Dropout معًا\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "7zfs_qQIw1cz"
      },
      "outputs": [],
      "source": [
        "combined_model = tf.keras.Sequential([\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu', input_shape=(FEATURES,)),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(512, kernel_regularizer=regularizers.l2(0.0001),\n",
        "                 activation='elu'),\n",
        "    layers.Dropout(0.5),\n",
        "    layers.Dense(1)\n",
        "])\n",
        "\n",
        "regularizer_histories['combined'] = compile_and_fit(combined_model, \"regularizers/combined\")"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "qDqBBxfI0Yd8"
      },
      "outputs": [],
      "source": [
        "plotter.plot(regularizer_histories)\n",
        "plt.ylim([0.5, 0.7])"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "tE0OoNCQNTJv"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "من الواضح أنّ النموذج الحالي الذّي يستعمل تقنيتي الضبط هو الأفضل حتّى الآن. \n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "-dw23T03FEO1"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "### عرض سجلاّت الإشراف على التدريب في TensorBoard\n",
        "\n",
        "جميع هذه النماذج كتبت سجلات TensorBoard أثناء التدريب.\n",
        "\n",
        "يمكنك أن تفتح عارض\n",
        "TensorBoard\n",
        "مضمّن داخل هذا الدّفتر التفاعلي هكذا:\n",
        "\n",
        "</div>\n",
        "\n",
        "```\n",
        "%tensorboard --logdir {logdir}/regularizers\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "KX3Voac-FEO4"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "يمكنك عرض [نتائج إحدى تجارب التدريب السابقة](https://tensorboard.dev/experiment/fGInKDo8TXes1z7HQku9mw/#scalars&_smoothingWeight=0.97) لهذا الدفتر التّفاعلي على موقع [TensorBoard.dev](https://tensorboard.dev/).\n",
        "\n",
        "يتم تضمينه أيضًا في \n",
        "`<iframe>`\n",
        "لتيسير التّعامل مع \n",
        "TensorBoard\n",
        "في هذا الدّفتر التفاعليّ:\n",
        "\n",
        "</div>\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "id": "doMtyYoqFEO5"
      },
      "outputs": [],
      "source": [
        "display.IFrame(\n",
        "    src=\"https://tensorboard.dev/experiment/fGInKDo8TXes1z7HQku9mw/#scalars&_smoothingWeight=0.97\",\n",
        "    width = \"100%\",\n",
        "    height=\"800px\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "mds5RXGjIcSu"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "تم تحميل هذا باستعمال الأمر التّالي:\n",
        "\n",
        "</div>\n",
        "\n",
        "```\n",
        "!tensorboard dev upload --logdir  {logdir}/regularizers\n",
        "```"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "uXJxtwBWIhjG"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "## الاستنتاجات\n",
        "\n",
        "</div>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "gjfnkEeQyAFG"
      },
      "source": [
        "<div dir=\"rtl\">\n",
        "\n",
        "للتلخيص: نجمع فيما يلي أكثر الطرق شيوعًا لمقاومة مشكلة الإفراط في التعلّم التّي قد تتعرّض إليها نماذج تعلّم الآلة في العموم و نماذج الشبكات العصبيّة بالخصوص:\n",
        "\n",
        "* احصل على المزيد من بيانات التدريب لجعل البيانات أكثر إكتمالاً.\n",
        "* تقليل سعة الشبكة عن طريق تقليل عدد طبقاتها و عدد الخلايا في كُلّ طبقة.\n",
        "* استعمال تقنية ضبط الأوزان (weight regularization).\n",
        "* استعمال تقنية الإسقاط العشوائي (Dropout).\n",
        "\n",
        "هناك طريقتان مهمتان لم يتمّ تناولهما في هذا الدليل وهما:\n",
        "\n",
        "* تكثير البيانات (data augmentation)\n",
        "* تعيير دُفعات البيانات (batch normalization)\n",
        "\n",
        "تذكّر أن كل طريقةٍ يمكنُ أن تساعد وحدها في تحسين أداء النّموذج ، ولكن غالبًا ما يكون الجمع بين طرق متعدّدة أكثر فعالية.\n",
        "\n",
        "</div>"
      ]
    }
  ],
  "metadata": {
    "accelerator": "GPU",
    "colab": {
      "collapsed_sections": [],
      "name": "overfit_and_underfit.ipynb",
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}
